package utils

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/rs/zerolog/log"
	"io/ioutil"
	"net"
	"net/http"
)

func HttpDo(url, method string, req, res interface{}) error {
	reqBuf, err := json.Marshal(req)
	if err != nil {
		return err
	}
	log.Info().Str("url", url).Str("request", string(reqBuf)).Msg(fmt.Sprintf("http %s", method))
	request, err := http.NewRequest(method, url, bytes.NewBuffer(reqBuf))

	if err != nil {
		return err
	}
	request.Header.Set("Content-Type", "application/json")
	response, err := http.DefaultClient.Do(request)
	if err != nil {
		return err
	}
	if response.StatusCode != http.StatusOK {
		return fmt.Errorf("status code %d", response.StatusCode)
	}
	resBody, err := ioutil.ReadAll(response.Body)
	log.Info().Str("url", url).Str("response", string(resBody)).Msg(fmt.Sprintf("http %s", method))
	if err != nil {
		return err
	}
	if res != nil {
		return json.Unmarshal(resBody, res)
	}
	return nil
}

func HttpDoWithHeader(url, method string, header map[string]string, req, res interface{}) error {
	reqBuf, err := json.Marshal(req)
	if err != nil {
		return err
	}
	log.Info().Str("url", url).Str("request", string(reqBuf)).Msg(fmt.Sprintf("http %s", method))
	request, err := http.NewRequest(method, url, bytes.NewBuffer(reqBuf))

	if err != nil {
		return err
	}
	request.Header.Set("Content-Type", "application/json")

	for k, v := range header {
		request.Header.Set(k, v)
	}
	response, err := http.DefaultClient.Do(request)
	if err != nil {
		return err
	}
	if response.StatusCode != http.StatusOK {
		return fmt.Errorf("status code %d", response.StatusCode)
	}
	resBody, err := ioutil.ReadAll(response.Body)
	log.Info().Str("url", url).Str("response", string(resBody)).Msg(fmt.Sprintf("http %s", method))
	if err != nil {
		return err
	}
	if res != nil {
		return json.Unmarshal(resBody, res)
	}
	return nil
}

func GetRemoteClientIp(r *http.Request) string {

	remoteIp := r.RemoteAddr

	if ip := r.Header.Get("X-Real-IP"); ip != "" {
		remoteIp = ip
	} else if ip = r.Header.Get("X-Forwarded-For"); ip != "" {
		remoteIp = ip
	} else {
		remoteIp, _, _ = net.SplitHostPort(remoteIp)
	}

	//本地ip
	if remoteIp == "::1" {
		remoteIp = "127.0.0.1"
	}

	return remoteIp
}
